package com.killer.context;

import com.killer.context.ApplicationContext;
import com.killer.factory.DefaultListableBeanFactory;
import com.killer.pojo.BeanDefinition;
import com.killer.pojo.PropertyValue;

import java.lang.reflect.Field;
import java.util.List;

/**
 * @author ：Killer
 * @date ：Created in 20-10-26 上午9:27
 * @description：${description}
 * @modified By：
 * @version: version
 */
public class AbstractApplicatonContext implements ApplicationContext{

    protected DefaultListableBeanFactory beanFactory;

    @Override
    public Object getBean(String name) throws Exception {
        //先从beanFactory获取
        Object object = beanFactory.getBean(name);
        if (object == null) {
            object=createBean(name);
        }
        return object;
    }

    private Object createBean(String name) throws Exception {
        //获取beanDefition
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
        if (beanDefinition == null) {
            throw new RuntimeException("bean:" + name + "未被注册");
        }
        Class<?> beanClass=beanDefinition.getBeanClass();
        Object object = beanClass.newInstance();
        //先提前暴露对象，解决循环依赖问题
        beanFactory.earlyEsposeObject(name, object);
        //完成属性赋值
        List<PropertyValue> propertyValueList=beanDefinition.getPropertyValueList();
        for (PropertyValue propertyValue : propertyValueList) {
            //获取字段名称
            String fieldName = propertyValue.getName();
            //获取该字段
            Field field = beanClass.getDeclaredField(fieldName);
            field.setAccessible(true);
            //如果value有值
            if (propertyValue.getValue() != null) {
                field.set(object, propertyValue.getValue());
            }else{
                //没有的话代表注入另一个bean对象
                field.set(object, getBean(propertyValue.getRef()));
            }
        }
        //对象创建完整后就将对象从二级缓存移到单例池中维护
        beanFactory.finishBeanCreation(name, object);
        return object;
    }

}
